package com.api.demo.test.pay_centre;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;

/**
 * @Author: ym
 * @Description: 招商银行
 * @Date: 2024/2/19 10:56
 * @Version: 1.0
 */
public class Zs extends Common {

    public static String bankApplicationId = "N002467299"; //银行应用ID （用户uid）
    public static String accountNo = "755915709610301"; //银行账户号  （银行一般户）
    public static String bankBranchCode = "10"; //招商分行号 （开户行）
    public static String busmod = "00003"; //业务模式 （网银配置）


    public static String signType = "RSA"; //私钥

    public static String requestUrl = "http://127.0.0.1:10009/api/pay/zs/"; //请求地址


    public static void main(String[] args) {
        //招行分行 查询
//        post(requestUrl + "cmbBankBranch", cmbBankBranch());

        //5.1.1可经办业务模式查询(DCLISMOD)
//        post(requestUrl + "dclismod", dclismod());

        //5.1.2账户详细信息查询(NTQACINF)
//        post(requestUrl + "ntqacinf", ntqacinf());

        //5.1.7账户交易信息查询GetTransInfo
//        post(requestUrl + "getTransInfo", getTransInfo());

        //1.1.1.1.1新增记账子单元NTDUMADD  -- 不建议使用()  可选：1.1.2.1新增记账子单元 NTDMAADD
//        post(requestUrl + "ntdumadd", ntdumadd());

        //1.1.1.1.3记账子单元查询NTDUMQRY -- 不建议使用()  可选：1.1.2.3 查询记账子单元信息NTDMALST
//        post(requestUrl + "ntdumqry", ntdumqry());

        //1.1.2.1新增记账子单元 NTDMAADD
//        post(requestUrl + "ntdmaadd", ntdmaadd());

        //1.1.2.3 查询记账子单元信息NTDMALST
//        post(requestUrl + "ntdmalst", ntdmalst());

        //1.1.2.5 设置记账子单元关联付款方信息NTDMARLT
//        post(requestUrl + "ntdmarlt", ntdmarlt());

        //1.1.2.6 修改记账子单元非关联付款方入式NTDMATMN
//        post(requestUrl + "ntdmatmn", ntdmatmn());

        //1.1.2.7 查询记账子单元关联付款方信息NTDMARLQ
//        post(requestUrl + "ntdmarlq", ntdmarlq());

        //1.1.2.8 删除记账子单元关联付款方信息NTDMARLD
//        post(requestUrl + "ntdmarld", ntdmarld());

        //1.1.2.15查询记账子单元余额NTDMABAL
//        post(requestUrl + "ntdmabal", ntdmabal());

        //单笔转账-下发单笔转账
//        post(requestUrl + "transfer", transfer());
        //单笔转账-内部转账
//        post(requestUrl + "transfer", interior_transfer());

        //批量交易
        post(requestUrl + "transferBatch", transferBatch());

//        post(Common.requestUrl + "transactionInfo", transactionInfo());


    }


    //测试使用，具体实现，由对接方实现，保证唯一即可 (具体记账子单元位数，由开户时选择的配置为准，推荐10位)
    public static String random(int num) {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < num; i++) {
            Random random = new Random();
            int nextInt = random.nextInt(10);
            str.append(nextInt);

        }
        return str.toString();
    }


    /**
     * 招行分行 查询
     */
    public static String cmbBankBranch() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);
//        data.put("level", 1);

        return encrypt(data);
    }

    /**
     * 5.1.1可经办业务模式查询(DCLISMOD)
     *
     * @return
     */
    public static String dclismod() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);
        data.put("buscod", "N03020");

        return encrypt(data);

    }

    /**
     * 5.1.2账户详细信息查询(NTQACINF)
     *
     * @return
     */
    public static String ntqacinf() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);
        List<Map<String, String>> list = new ArrayList<>();
        Map<String, String> d1 = new HashMap<>();
        d1.put("bbknbr", bankBranchCode);
        d1.put("accnbr", accountNo);

        list.add(d1);
        data.put("ntqacinfx", list);

        return encrypt(data);

    }

    /**
     * 5.1.7账户交易信息查询GetTransInfo
     *
     * @return
     */
    private static String getTransInfo() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);

        //查询条件
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> d1 = new HashMap<>();
        d1.put("bbknbr", bankBranchCode);
//        d1.put("c_bbknbr", "");
        d1.put("accnbr", accountNo);
        d1.put("bgndat", "20240101");
        d1.put("enddat", "20240104");
//        d1.put("lowamt", new BigDecimal("1.11"));
//        d1.put("hghamt", new BigDecimal("1.11"));
//        d1.put("amtcdr", "");

        list.add(d1);
        data.put("sdktsinfx", list);

        //续传接口
//        List<Map<String, Object>> list2 = new ArrayList<>();
//        Map<String, Object> d2 = new HashMap<>();
//        d1.put("ctndta", "755915709660000&20231110&193");
//        d1.put("rsv50z", "");
//        list2.add(d2);
//        data.put("ntqacctny", list2);


        return encrypt(data);

    }

    /**
     * 1.1.1.1.1新增记账子单元NTDUMADD
     *
     * @return
     */
    private static String ntdumadd() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);

        //查询条件
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> d1 = new HashMap<>();
        d1.put("busmod", "00003");
        list.add(d1);
        data.put("ntbusmody", list);

        //
        List<Map<String, Object>> list2 = new ArrayList<>();
        Map<String, Object> d2 = new HashMap<>();
        d2.put("bbknbr", bankBranchCode);
        d2.put("inbacc", accountNo);
        d2.put("dyanbr", random(10));
        d2.put("dyanam", "测试商户");
        d2.put("eftdat", LocalDate.now().toString().replaceAll("-", "")); //yyyyMMdd
        d2.put("yurref", System.currentTimeMillis());
        d2.put("ovrctl", "N");
        list2.add(d2);
        data.put("ntdumaddx1", list2);
        return encrypt(data);
    }

    /**
     * 1.1.1.1.3记账子单元查询NTDUMQRY
     *
     * @return
     */
    private static String ntdumqry() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);

        //查询条件
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> d1 = new HashMap<>();
        d1.put("bbknbr", bankBranchCode);
        d1.put("inbacc", accountNo);
//        d1.put("danbeg", "********************");   //20个 * 查询所有
        d1.put("danbeg", "1080575696");   //20个 * 查询所有
//        d1.put("danend", "********************");   //20个 * 查询所有
        d1.put("danend", "1080575696");   //20个 * 查询所有
//        d1.put("ctnkey", "4037948583");
        list.add(d1);
        data.put("ntdumqryy1", list);
        return encrypt(data);
    }

    /**
     * 1.1.2.1新增记账子单元 NTDMAADD
     *
     * @return
     */
    private static String ntdmaadd() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);

        //查询条件
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> d1 = new HashMap<>();
        d1.put("accnbr", accountNo);
        d1.put("dmanbr", random(10));
//        d1.put("dmanbr", "5400580881");
        d1.put("dmanam", "测试账户");
        d1.put("ovrctl", "N");
        d1.put("bcktyp", "Y");
        d1.put("clstyp", "Y");
        list.add(d1);
        data.put("ntdmaaddx", list);
        return encrypt(data);
    }

    /**
     * 1.1.2.3 查询记账子单元信息NTDMALST
     *
     * @return
     */
    private static String ntdmalst() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);

        //查询条件
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> d1 = new HashMap<>();
        d1.put("accnbr", accountNo);
//        d1.put("dmanbr", "");   //为空查询所有
        d1.put("dmanbr", "5400580881");   //为空查询所有
//        d1.put("rsv50z", "");
        //d1.put("ctnkey", "");
        list.add(d1);
        data.put("ntdmalstx", list);
        return encrypt(data);
    }

    /**
     * 1.1.2.5 设置记账子单元关联付款方信息NTDMARLT
     *
     * @return
     */
    private static String ntdmarlt() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);


        //查询条件
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> d1 = new HashMap<>();
        d1.put("bbknbr", bankBranchCode);
        d1.put("accnbr", accountNo);
        d1.put("dmanbr", "6468235474");
        d1.put("tlyopr", "R");
        d1.put("yurref", System.currentTimeMillis());


        //以下方式三选一 根据实际业务选择

//        d1.put("dbtacc", "300000000000000");
//        list.add(d1);
//        data.put("ntdmarltx1", list);

//        d1.put("dbtnam", "测试商户");
//        list.add(d1);
//        data.put("ntdmarltx2", list);

        d1.put("dbtamt", "123.43");
        list.add(d1);
        data.put("ntdmarltx3", list);

        return encrypt(data);
    }

    /**
     * 1.1.2.6 修改记账子单元非关联付款方入式NTDMATMN
     *
     * @return
     */
    private static String ntdmatmn() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);

        //查询条件
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> d1 = new HashMap<>();
        d1.put("accnbr", accountNo);
        d1.put("bbknbr", bankBranchCode);
        d1.put("dmanbr", "6468235474");
        d1.put("tlyopr", "R");
        list.add(d1);
        data.put("ntdmatmnx1", list);
        return encrypt(data);
    }


    /**
     * 1.1.2.7 查询记账子单元关联付款方信息NTDMARLQ
     *
     * @return
     */
    private static String ntdmarlq() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);

        //查询条件
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> d1 = new HashMap<>();
        d1.put("accnbr", accountNo);
        d1.put("bbknbr", bankBranchCode);
        d1.put("dmanbr", "6468235474");
//        d1.put("cntkey", "");
        list.add(d1);
        data.put("ntdmarlqy1", list);
        return encrypt(data);
    }


    /**
     * 1.1.2.8 删除记账子单元关联付款方信息NTDMARLD
     *
     * @return
     */
    private static String ntdmarld() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);


        //查询条件
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> d1 = new HashMap<>();
        d1.put("bbknbr", bankBranchCode);
        d1.put("accnbr", accountNo);
        d1.put("dmanbr", "6468235474");
        d1.put("yurref", System.currentTimeMillis());


        //以下方式三选一 根据实际业务选择

        d1.put("dbtacc", "300000000000000");
        list.add(d1);
        data.put("ntdmarldx1", list);

//        d1.put("dbtnam", "测试商户");
//        list.add(d1);
//        data.put("ntdmarldx2", list);

//        d1.put("dbtamt", "123.32");
//        list.add(d1);
//        data.put("ntdmarldx3", list);

        return encrypt(data);
    }

    /**
     * 1.1.2.15查询记账子单元余额NTDMABAL
     *
     * @return
     */
    private static String ntdmabal() {
        Map<String, Object> data = new HashMap<>();
        data.put("bankApplicationId", bankApplicationId);

        //查询条件
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> d1 = new HashMap<>();
        d1.put("accnbr", accountNo);
//        d1.put("bbknbr", bankBranchCode);
//        d1.put("dmanbr", "0000000000");  //空查询所有
        d1.put("dmanbr", "6468235474");  //空查询所有
//        d1.put("rsv50z", "");
        list.add(d1);
        data.put("ntdmabalx", list);
        return encrypt(data);
    }


//    /**
//     * 1.1.2.22单笔设置交易管家（记账）白名单NTDMAWLS
//     *
//     * @return
//     */
//    private static String ntdmawls() {
//        Map<String, Object> data = new HashMap<>();
//        data.put("bankApplicationId", bankApplicationId);
//
//        //查询条件
//        List<Map<String, Object>> list = new ArrayList<>();
//        Map<String, Object> d1 = new HashMap<>();
//        d1.put("accnbr", accountNo);
//        d1.put("bbknbr", bankBranchCode);
//        d1.put("dmanbr", "6468235474");
//        d1.put("sndacc", "300000000000000");
//        d1.put("sndnam", "某某有限公司");
//        d1.put("chktyp", "1");
//        d1.put("yurref", System.currentTimeMillis());
//        d1.put("RCVTYP", "R");
////        d1.put("rsv50z", "");
//        list.add(d1);
//        data.put("ntdmawlsx1", list);
//
//        //
//        List<Map<String, Object>> list2 = new ArrayList<>();
//        Map<String, Object> d2 = new HashMap<>();
//        d2.put("busmod", busmod);
//        list2.add(d2);
//        data.put("ntbusmody", list2);
//
//        return encrypt(data);
//    }


    /**
     * 单笔转账-下发单笔转账
     *
     * @return
     */
    private static String transfer() {
        Map<String, Object> d1 = new HashMap<>();
        long orderNo = System.currentTimeMillis();
        System.out.println("订单号:" + orderNo);
        d1.put("bankApplicationId", bankApplicationId);
        d1.put("businessOrderId", orderNo); //测试使用 实际需输入唯一的订单号
        d1.put("businessSubOrderId", "");

        d1.put("amount", new BigDecimal("1.32"));
//        d1.put("remarks", "我是备注");
        d1.put("remarks", "我是备注1234124141234123131312");
        d1.put("businessTag", "");
        d1.put("businessCallbackUrl", "");
        d1.put("accountIdCardTo", "");
        Map<String, BigDecimal> linkedHashMap = null;

//        linkedHashMap = new LinkedHashMap<>();
//        linkedHashMap.put("PAYEE_MONTH", new BigDecimal("9.99"));//PAYEE_MONTH("PAYEE_MONTH", "收款方月限额"),
//        linkedHashMap.put("PAYEE_YEAR", new BigDecimal("99.99"));//PAYEE_YEAR("PAYEE_YEAR", "收款方年限额"),
//
        d1.put("amountLimitDto", linkedHashMap); //限额信息
        d1.put("parkId", "");
        d1.put("accountNumberFrom", "0000000000");
        d1.put("accountOwnerFrom", "测试商户");

        //内部转账
//        d1.put("tradeChannel", 1011);  //1011 内部转账（子账户转账） 、 1012 银行卡下发）
//        d1.put("accountNumberTo", "6468235474");
//        d1.put("accountOwnerTo", "测试商户");

        //银行卡下发
        d1.put("tradeChannel", 1012);  //1011 内部转账（子账户转账） 、 1012 银行卡下发）
        d1.put("accountNumberTo", "6214831150131511");
        d1.put("accountOwnerTo", "吴极客");

        d1.put("sameBank", true);
        d1.put("bankNodeTo", "");

        //主账户信息
        Map<String, Object> mainAccountDto = new HashMap<>();
        mainAccountDto.put("mainAccount", accountNo);
        mainAccountDto.put("mainAccountName", "测试");
        mainAccountDto.put("branchNo", bankBranchCode);
        d1.put("mainAccountDto", mainAccountDto);

        return encrypt(d1);
    }


    /**
     * 单笔转账-内部转账
     */
    private static String interior_transfer() {
        Map<String, Object> d1 = new HashMap<>();
        long orderNo = System.currentTimeMillis();
        System.out.println("订单号:" + orderNo);
        d1.put("bankApplicationId", bankApplicationId);
        d1.put("businessOrderId", orderNo); //测试使用 实际需输入唯一的订单号
        d1.put("businessSubOrderId", "");

        d1.put("amount", new BigDecimal("1.32"));
        d1.put("remarks", "我是备注");
        d1.put("businessTag", "");
        d1.put("businessCallbackUrl", "");
        d1.put("accountIdCardTo", "");

        d1.put("amountLimitDto", null); //限额信息
        d1.put("parkId", "");
        d1.put("accountNumberFrom", "0000000000");
        d1.put("accountOwnerFrom", "测试商户");

        //内部转账
        d1.put("tradeChannel", 1011);  //1011 内部转账（子账户转账） 、 1012 银行卡下发）
        d1.put("accountNumberTo", "6468235474");
        d1.put("accountOwnerTo", "测试商户");


        d1.put("sameBank", true);
        d1.put("bankNodeTo", "");

        //主账户信息
        Map<String, Object> mainAccountDto = new HashMap<>();
        mainAccountDto.put("mainAccount", accountNo);
        mainAccountDto.put("mainAccountName", "测试");
        mainAccountDto.put("branchNo", bankBranchCode);
        d1.put("mainAccountDto", mainAccountDto);

        return encrypt(d1);
    }


    /**
     * 批量转账
     *
     * @return
     */
    private static String transferBatch() {

        Map<String, Object> d1 = new HashMap<>();
        d1.put("bankApplicationId", bankApplicationId);

        //批量明细
        List<Map<String, Object>> transferDtoList = new ArrayList<>();

        long orderNo = System.currentTimeMillis();
        System.out.println("订单号:" + orderNo);

        //限额信息
        Map<String, BigDecimal> linkedHashMap = null;
//        linkedHashMap = new LinkedHashMap<>();
//        linkedHashMap.put("PAYEE_MONTH", new BigDecimal("9.99"));//PAYEE_MONTH("PAYEE_MONTH", "收款方月限额"),
//        linkedHashMap.put("PAYEE_YEAR", new BigDecimal("99.99"));//PAYEE_YEAR("PAYEE_YEAR", "收款方年限额"),
//


//        批量基础信息
        Map<String, Object> batchBaseInfoDto = new HashMap<>();
        batchBaseInfoDto.put("businessBatchId", orderNo);
        batchBaseInfoDto.put("thirdMerchantCode", bankApplicationId);
        batchBaseInfoDto.put("tradeChannel", 1012);
        batchBaseInfoDto.put("accountNumberFrom", "0000000000");
        batchBaseInfoDto.put("accountOwnerFrom", "测试商户");
        batchBaseInfoDto.put("totalAmount", new BigDecimal("20.24"));
        batchBaseInfoDto.put("totalNum", 2);
        batchBaseInfoDto.put("remarks", "测试款");
        batchBaseInfoDto.put("parkId", "1");

        d1.put("batchBaseInfoDto", batchBaseInfoDto); //  批量基础信息


        //主账户信息
//        Map<String, Object> mainAccountDto = new HashMap<>();
//        mainAccountDto.put("mainAccount", accountNo);
//        mainAccountDto.put("mainAccountName", "测试");
//        mainAccountDto.put("branchNo", bankBranchCode); //招商银行必填
        d1.put("mainAccountDto", getMainAccount()); //  主账户信息


        //下发人员1
        Map<String, Object> transferDto = new HashMap<>();
        transferDto.put("businessOrderId", orderNo + 11);
        transferDto.put("businessSubOrderId", orderNo + 1);
        transferDto.put("thirdMerchantCode", bankApplicationId);
        transferDto.put("tradeChannel", 1012);
        transferDto.put("amount", new BigDecimal("10.12"));
        transferDto.put("remarks", "灵活用工费用结算");
//        transferDto.put("businessTag", "");
//        transferDto.put("businessCallbackUrl", "");
        transferDto.put("accountIdCardTo", "123123123123");
        transferDto.put("amountLimitDto", linkedHashMap);
        transferDto.put("parkId", "1");
        transferDto.put("accountNumberTo", "6214831150131511");
        transferDto.put("accountOwnerTo", "吴极客");
        transferDto.put("accountNumberFrom", "0000000000");
        transferDto.put("accountOwnerFrom", "测试商户");
        transferDto.put("sameBank", true); //招商、平安 需要提供
        transferDto.put("bankNodeTo", "");
        transferDto.put("mainAccountDto", getMainAccount());
        transferDtoList.add(transferDto);
        // ---------------  ---------------


        //下发人员1
        Map<String, Object> transferDto1 = new HashMap<>();
        transferDto1.put("businessOrderId", orderNo + 12);
        transferDto1.put("businessSubOrderId", orderNo + 2);
        transferDto1.put("thirdMerchantCode", bankApplicationId);
        transferDto1.put("tradeChannel", 1012);
        transferDto1.put("amount", new BigDecimal("10.12"));
        transferDto1.put("remarks", "灵活用工费用结算");
//        transferDto.put("businessTag", "");
//        transferDto.put("businessCallbackUrl", "");
        transferDto1.put("accountIdCardTo", "123123123123");
        transferDto1.put("amountLimitDto", linkedHashMap);
        transferDto1.put("parkId", "1");
        transferDto1.put("accountNumberTo", "6214835982629402");
        transferDto1.put("accountOwnerTo", "冯建杨");
        transferDto1.put("accountNumberFrom", "0000000000");
        transferDto1.put("accountOwnerFrom", "测试商户");
        transferDto1.put("sameBank", true); //招商、平安 需要提供
        transferDto1.put("bankNodeTo", "");
        transferDto1.put("mainAccountDto", getMainAccount());
        transferDtoList.add(transferDto1);
        // ---------------  ---------------


        //批量明细
        d1.put("transferDtoList", transferDtoList);

        return encrypt(d1);
    }


    public static Map<String, Object> getMainAccount() {
        Map<String, Object> mainAccountDto = new HashMap<>();
        mainAccountDto.put("mainAccount", accountNo);
        mainAccountDto.put("mainAccountName", "测试");
        mainAccountDto.put("branchNo", bankBranchCode); //招商银行必填
        return mainAccountDto;
    }



}
